#include <iostream>
#include <unistd.h>
#include <cerrno>
#include <string.h>
#include <cassert>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

//管道的模拟实现

int main(){
    int pipefd[2] = {0};
    // 1、创建管道
    int n = pipe(pipefd);
    if (n < 0){
        cout << "pipe error, " << errno << ":" << strerror(errno) << endl;
        return 1;
    }
    cout << "pipefd[0]: " << pipefd[0] << endl; //读端
    cout << "pipefd[1]: " << pipefd[1] << endl; //写端

    //2、创建子进程
    pid_t id = fork();
    //只考虑fork成功的情况  --  意料之外用if，意料之中用assert
    assert(id != -1);
    if(id == 0){
        //子进程
        //3、关闭不需要的fd --  根据实际情况，这里规定父进程读，子进程写
        close(pipefd[0]);

        //4、开始通信   --  结合某种场合
        string name = "child";
        int cnt = 0;
        char buffer[1024];
        while(1){

            // snprintf(buffer, sizeof(buffer), "%s, 计数器: %d, PID: %d   ----    ", name.c_str(), cnt++, getpid());
            // write(pipefd[1], buffer, strlen(buffer));
            // sleep(2);

            //不用缓冲区直接向管道文件中写入
            char x = 'X';
            write(pipefd[1], &x, 1);
            cout << "cnt = " << cnt++ << endl;
            // if(cnt == 5){
            //     break;
            // }
            sleep(1);
                }

        close(pipefd[1]);
        exit(0);
    }
    //父进程
    //3、关闭不需要的fd --  根据实际情况，这里规定父进程读，子进程写
    close(pipefd[1]);
    int cnt = 0;
    //4、开始通信
    char buffer[1024];
    while (1){
        sleep(1);
        int n = read(pipefd[0], buffer, sizeof(buffer) - 1);
        if(n>0){
            buffer[n] = '\0';
            cout << "obtained message: " << buffer << endl;
        }else if(n==0){
            cout << "finish" << endl;
            break;
        }else{
            cout << "err" << endl;
            break;
        }
        
        if (cnt++ > 5)
        {
            break;
        }
    }
    close(pipefd[0]);

    int status = 0;
    waitpid(id, &status, 0);
    cout << "sig: " << (status & 0x7F) << endl;
    return 0;
}